/**
 * Copyright (c), 上海沃恩信息科技有限公司.
 * All rights reserved.
 * Licensed under BSD (https://www.pittypat.work/bsd.html).
 */

package pittypat;

import pittypat.configuration.PittypatConfig;

/**
 * 默认的授权服务。该服务不执行任何操作，也不会产生异常。不能从外部创建该类的对象实例。
 */
public final class AuthorityService implements IAuthorityService {
	/*
	 * AuthorityService 的默认对象实例。
	 */
	private static final AuthorityService DEFAULT_INSTANCE = new AuthorityService();

	// 当前服务
	private static IAuthorityService currentService = null;
	// 同步对服务的访问
	private static final Object CURRENT_SERVICE_LOCK = new Object();

	/**
	 * 获取当前配置文件中定义的安全验证服务。
	 * 
	 * @return 一个 IAuthorityService 对象。
	 * @throws ClassNotFoundException
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	public static IAuthorityService getCurrent()
			throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		if (currentService == null) {
			synchronized (CURRENT_SERVICE_LOCK) {
				if (currentService == null) {
					String typeName = PittypatConfig.getCurrent().getAuthorityService();

					if (typeName == null || typeName.length() == 0) {
						currentService = DEFAULT_INSTANCE;
					} else {
						Class<?> type = Class.forName(typeName);
						if (type == null) {
							throw new ClassNotFoundException("没有找到作为用户验证服务的类型定义：" + typeName + "。");
						}

						currentService = (IAuthorityService) type.newInstance();
					}
				}
			}
		}

		return currentService;
	}

	/*
	 * 初始化 AuthorityService 的新实例。
	 */
	private AuthorityService() {
	}

	/**
	 * 获取当前系统在目标授权服务中的系统令牌。默认实现总是返回空字符串。
	 * 
	 * @param systemId
	 *            系统的 Id。
	 * @param systemKey
	 *            系统的密钥。
	 * @param progress
	 *            跟踪和汇报异步操作的进度。
	 * @return 系统令牌。
	 */
	@Override
	public String getSystemToken(String systemId, String sytemKey, IAsyncProgress progress) {
		return "";
	}

	/**
	 * 使用指定的用户名和密码登录当前系统。默认实现总是返回空字符串。
	 * 
	 * @param systemToken
	 *            系统令牌。
	 * @param loginName
	 *            用户登录名称。
	 * @param password
	 *            用户登录密码的明文。
	 * @param progress
	 *            跟踪和汇报异步操作的进度。
	 * @return 如果登录成功，则返回用户令牌，否则返回 null 或空字符串。
	 */
	@Override
	public LoginResult login(String systemToken, String loginName, String password, IAsyncProgress progress) {
		return LoginResult.ANONYMOUS;
	}

	/**
	 * 注销指定令牌的用户。默认实现什么都不做。
	 * 
	 * @param systemToken
	 *            系统令牌。
	 * @param userToken
	 *            要注销的用户的用户令牌。
	 * @param progress
	 *            跟踪和汇报异步操作的进度。
	 */
	@Override
	public void logout(String systemToken, String userToken, IAsyncProgress progress) {
	}

	/**
	 * 验证指定的用户是否对指定路径的功能具有权限。默认实现总是返回匿名的未授权的权限。
	 * 
	 * @param systemToken
	 *            系统令牌。
	 * @param userToken
	 *            用户令牌。
	 * @param funcPath
	 *            目标功能的完整路径。当传递空引用或空字符串时，用于返回指定令牌的用户的用户信息。
	 * @param progress
	 *            跟踪和汇报异步操作的进度。
	 * @return 返回作为验证结果的用户和授权信息，如果返回空引用，则使用未授权的匿名用户。
	 */
	@Override
	public Permission demand(String systemToken, String userToken, String funcPath, IAsyncProgress progress) {
		return Permission.ANONYMOUS_UNAUTHORIZED;
	}

	/**
	 * 加载指定用户拥有权限的所有 App 和模块的列表，也就是导航列表。默认实现总是返回一个空导航列表。
	 * 
	 * @param systemToken
	 *            系统令牌。
	 * @param userToken
	 *            用户令牌。
	 * @param progress
	 *            跟踪和汇报异步操作的进度。
	 * @return 指定用户拥有权限的 App 和模块的导航列表。
	 */
	@Override
	public NavList navList(String systemToken, String userToken, IAsyncProgress progress) {
		return NavList.EMPTY;
	}
}
